<?php
namespace bc\util;
use yii;
class Concurrency{
    private $object;        //初始化对象,STRING
    private $number;        //单品活动数量  INT
    private $prefix;        //对应key值的前缀,保证全局唯一,STRING
    private $onlyOne;       //每个用户是否只能领取一次,BOOLE
    private $uniqueCode;    //唯一标识。(避免生成key重复。不同时间做同一个活动）,时间戳
    public static $connect; //连接资源 RESOURCES
    private $end_active_key="active_end_d5c90dbc229e9046f6491bdf6679";
    public function __construct($object,$number,$prefix,$uniqueCode,$onlyOne=false)
    {
        $this->object=$object;
        $this->number=$number;
        $this->prefix=$prefix;
        $this->onlyOne=$onlyOne;
        $this->uniqueCode=$uniqueCode;
        $this->connect();
    }

    /**
     * Created by Mr.hu.
     * Description:抢操作,返回抢购结果 boole
     */
    public function run()
    {
        if(!$this->isInitialized()){
            $this->_init();
        }

        if($this->robEmpty()){
            return false;
        }

        $UniqueKey=$this->getUniqueKey();
        //开启事务
        self::$connect->WATCH($UniqueKey);
        self::$connect->MULTI();
        self::$connect->LPOP($UniqueKey);
        self::$connect->LLEN($UniqueKey);
        $result=self::$connect->EXEC();//pop出去的数据，以数组的形式返回
        if($result[1]==0){
            self::$connect->SADD($this->end_active_key,$this->getUniqueKey());
        }
        return $result[0]?true:false;
    }

    /**
     * Created by Mr.hu.
     * Description:检查抢空  抢空：true    还有剩余：false
     */
    private function robEmpty()
    {
        return self::$connect->SISMEMBER($this->end_active_key,$this->getUniqueKey())?true:false;
    }

    /**
     * Created by Mr.hu.
     * Description:是不是抢完结束了,true表示结束 false表示进行中
     */
    public function is_end()
    {
        return self::$connect->SISMEMBER($this->end_active_key,$this->getUniqueKey());
    }
    


    /**
     * Created by Mr.hu.
     * Description:初始化数据,生成相应的队列
     */
    public function _init()
    {
        $list_key=$this->getUniqueKey();
        self::$connect->DEL($list_key);
        for($i=0;$i< $this->number;$i++){
            self::$connect->LPUSH($list_key,uniqid());
        }
    }

    /**
     * Created by Mr.hu.
     * Description:某一对象是否已经初始化
     */
    public function isInitialized()
    {
        //检查活动是否已经结束
        return self::getConnect()->EXISTS($this->getUniqueKey());
    }

    /**
     * Created by Mr.hu.
     * Description:获取list的key
     */
    public function getUniqueKey()
    {
        $key=$this->prefix.'_'.$this->object.'_'.$this->uniqueCode;
        return $key;
    }



    /**
     * Created by Mr.hu.
     * Description:获取连接资源
     */
    public static function getConnect()
    {
        return static::$connect;
    }




    /**
     * Created by Mr.hu.
     * Description:连接
     */
    private function connect()
    {
        $redis = yii::$app->redis;
        self::$connect=$redis;
    }
}